package main

import (
	"flag"
	"fmt"
	"io"
	"net"
	"os"
)

type Client struct {
	IpAddr string
	Port   int
	Name   string
	Conn   net.Conn
}

var (
	Ip   string
	Port int
)

func init() {
	flag.StringVar(&Ip, "h", "127.0.0.1", "服务器IP地址，默认127.0.0.1")
	flag.IntVar(&Port, "p", 8848, "服务器端口，默认8848")
}

func NewClient() *Client {
	client := &Client{
		IpAddr: Ip,
		Port:   Port,
	}

	serviceAddr := fmt.Sprintf("%s:%d", client.IpAddr, client.Port)
	conn, error := net.Dial("tcp", serviceAddr)
	if error != nil {
		fmt.Println("建立建立连接到服务器失败：", error)
	}

	client.Conn = conn

	return client
}

func (client *Client) Run() {
	var cmd int
	for {

		fmt.Println("请输入相关命令进行操作")
		fmt.Println("1.更改用户名")
		fmt.Println("2.私聊")
		fmt.Println("3.群聊")
		fmt.Println("4.查看在线用户")
		fmt.Println("0.退出系统")
		fmt.Scanln(&cmd)

		if cmd > -1 && cmd < 5 {
			// 输入有效
			switch cmd {
			case 1:
				fmt.Println("用户输入了1，选择了更改用户名")
				client.changeName()
				break
			case 2:
				fmt.Println("用户输入了2，选择了私聊")
				break
			case 3:
				fmt.Println("用户输入了3，选择了群聊")
				client.broadcast()
				break
			case 4:
				fmt.Println("用户输入了4，选择了查看在线用户")
				client.onlineUser()
				break
			case 0:
				fmt.Println("用户输入了0，选择了退出系统")
				client.Offline()
				break
			default:
				fmt.Println("用户输入了无效数字，请重新输入")
				break
			}
		}
	}
}

func (client *Client) changeName() bool {
	fmt.Println("请输入您想修改的名字，按回车键结束")
	// var newName string
	fmt.Scanln(&client.Name)

	cmd := fmt.Sprintf("rename@%s", client.Name)

	_, err := client.Conn.Write([]byte(cmd + "\n"))
	if err != nil {
		fmt.Println("修改名称失败！:", err)
		return false
	}
	return true
}

func (client *Client) broadcast() bool {
	var msg string
	for {
		fmt.Println("请输入您想发送的消息，输入exit退出")

		fmt.Scanln(&msg)
		if msg != "exit" {
			_, err := client.Conn.Write([]byte(msg + "\n"))
			if err != nil {
				fmt.Println("消息发送失败！:", err)
			}
		} else {
			break
		}
	}
	// cmd := fmt.Sprintf("rename@%s", client.Name)

	return true
}

func (client *Client) onlineUser() bool {
	_, err := client.Conn.Write([]byte("online\n"))
	if err != nil {
		fmt.Println("查看在线用户失败！:", err)
		return false
	}
	return true
}

func (client *Client) Offline() bool {
	_, err := client.Conn.Write([]byte("\n"))
	if err != nil {
		fmt.Println("下线！:", err)
		return false
	}
	return true
}

func (client *Client) ListenServerMsg() {
	io.Copy(os.Stdout, client.Conn)
	// 单开协程监听服务器发送过来的信息
	// msgByte := [4096]byte{}
	// for {
	// 	size, error := client.Conn.Read(msgByte[:])
	// 	if error != nil {
	// 		fmt.Println("从服务器读取消息失败：", error)
	// 	}

	// 	if size > 0 {
	// 		fmt.Println("服务器消息:", msgByte)
	// 	}
	// }
}

func main() {
	// 命令行解析
	flag.Parse()

	client := NewClient()

	// 客户端操作
	go client.Run()

	// 监听服务器发送的消息
	go client.ListenServerMsg()

	select {}
}
